package com.tencent.live;

import android.Manifest;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.tencent.liteav.TXLiteAVCode;
import com.tencent.liteav.debug.Constant;
import com.tencent.live.http.ContextHolder;
import com.tencent.live.http.HttpUtil;
import com.tencent.live.utils.PicUtils;
import com.tencent.live.view.storage.TenCentStorageActivity;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;

import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 基类，主要是公用的控件和 Android 系统权限动态申请
 */
public abstract class LiveBaseActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "LiveBaseActivity";
    private  int REQUEST_GET_IMAGE = 1;

    protected static final int REQ_PERMISSION_CODE  = 0x1000;
    protected static final int DEFAULT_CAPACITY     = 5;

    protected TXCloudVideoView                mAnchorPreviewView;         // 主播画面View
    protected LiveSubVideoView                mLinkMicSelfPreviewView;    // 位置1连麦后画面View
    protected Button                          mSwitchCameraButton;        // 切换摄像头
    protected Button                          mMuteVideoButton;           // 关闭/打开画面
    protected Button                          mMuteAudioButton;           // 关闭/打开声音
    protected ImageView                       mBackButton;                // 页面顶部返回按钮
    protected TextView                        mTitleText;                 // 页面顶部标题
    protected LinearLayout                    mBigPreviewMuteVideoDefault;// 主画面关闭画面后默认图
    protected Button                          mLogInfoButton;             // 关闭/打开日志信息
    protected Button                          mSendMsgButton;             // 发送消息
    protected Button                          mChoosePhotoButton;         // 跳转系统相册
    protected ImageView                       mShowImg;                   // 显示已选择编辑好的照片

    protected TRTCCloud                       mTRTCCloud;                 // SDK 核心类
    protected TRTCCloudDef.TRTCParams         mTRTCParams;                // SDK 参数
    protected boolean                         mIsFrontCamera = true;      // 默认摄像头前置

    protected int                             mGrantedCount = 0;          // 权限个数计数，获取Android系统权限
    protected int                             mRoleType;                  // 房间角色类型
    protected int                             mLogLevel = 0;              // 日志等级
    protected String                          mRoomId;                    // 房间Id
    protected String                          mUserId;                    // 用户Id
    protected String                          mRoomCode;                    // 房间邀请码
    protected String                          mMainRoleAnchorId;          // 大主播Id（Demo中为演示和roomId相同）

    protected List<String>                    mRemoteUidList;             // 远端用户列表（不包括位置1用户）
    protected List<LiveSubVideoView>          mRemoteViewList;            // 远端画面列表（不包括位置1用户）
    protected LiveRoomManager                 mLiveRoomManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live);
        getSupportActionBar().hide();
        handleIntent();

        mTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());
        mTRTCCloud.setListener(new TRTCCloudImplListener(LiveBaseActivity.this));
        mLiveRoomManager = new LiveRoomManager();
    }

    protected void initView() {
        mBackButton                 = findViewById(R.id.ic_back);
        mTitleText                  = findViewById(R.id.tv_room_number);
        mMuteVideoButton            = findViewById(R.id.live_btn_mute_video);
        mMuteAudioButton            = findViewById(R.id.live_btn_mute_audio);
        mSwitchCameraButton         = findViewById(R.id.live_btn_switch_camera);
        mAnchorPreviewView          = findViewById(R.id.live_cloud_view_main);
        mLogInfoButton              = findViewById(R.id.live_btn_log_info);
        mSendMsgButton              = findViewById(R.id.live_btn_send_msg);
        mChoosePhotoButton          = findViewById(R.id.live_btn_choose_photo);
        mShowImg                    = findViewById(R.id.img_show);
        mBigPreviewMuteVideoDefault = findViewById(R.id.ll_big_preview_default);
        mLinkMicSelfPreviewView     = findViewById(R.id.live_cloud_view_1); // 位置1画面View

        mMainRoleAnchorId = mRoomId;
        if (!TextUtils.isEmpty(mRoomId)) {
            mTitleText.setText(mRoomId);
        }

        mRemoteUidList = new ArrayList<>(DEFAULT_CAPACITY);
        mRemoteViewList = new ArrayList<>(DEFAULT_CAPACITY);

        mRemoteViewList.add((LiveSubVideoView)findViewById(R.id.live_cloud_view_2));
        mRemoteViewList.add((LiveSubVideoView)findViewById(R.id.live_cloud_view_3));
        mRemoteViewList.add((LiveSubVideoView)findViewById(R.id.live_cloud_view_4));
        mRemoteViewList.add((LiveSubVideoView)findViewById(R.id.live_cloud_view_5));
        mRemoteViewList.add((LiveSubVideoView)findViewById(R.id.live_cloud_view_6));

        mBackButton.setOnClickListener(this);
        mLogInfoButton.setOnClickListener(this);
        mSendMsgButton.setOnClickListener(this);
        mChoosePhotoButton.setOnClickListener(this);
    }

    private void handleIntent() {
        Intent intent = getIntent();
        if (null != intent) {
            if (intent.getStringExtra(Constant.USER_ID) != null) {
                mUserId = intent.getStringExtra(Constant.USER_ID);
            }
            if (intent.getStringExtra(Constant.USER_ROOMCODE) != null) {
                mRoomCode = intent.getStringExtra(Constant.USER_ROOMCODE);
            }
            if (intent.getStringExtra(Constant.ROOM_ID) != null) {
                mRoomId = intent.getStringExtra(Constant.ROOM_ID);
            }
            if (intent.getIntExtra(Constant.ROLE_TYPE, 0) != 0) {
                mRoleType = intent.getIntExtra(Constant.ROLE_TYPE, 0);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        exitRoom();
        mLiveRoomManager.destoryLiveRoom(mRoomId);
        //销毁 trtc 实例
        if (mTRTCCloud != null) {
            mTRTCCloud.setListener(null);
        }
        mTRTCCloud = null;
        TRTCCloud.destroySharedInstance();
    }

    protected void switchCamera() {
        if (mIsFrontCamera) {
            mIsFrontCamera = false;
            mSwitchCameraButton.setBackgroundResource(R.mipmap.live_camera_back);
        } else {
            mIsFrontCamera = true;
            mSwitchCameraButton.setBackgroundResource(R.mipmap.live_camera_front);
        }
        mTRTCCloud.switchCamera();
    }

    protected class TRTCCloudImplListener extends TRTCCloudListener {

        private WeakReference<LiveBaseActivity> mContext;

        public TRTCCloudImplListener(LiveBaseActivity activity) {
            super();
            mContext = new WeakReference<>(activity);
        }

        @Override
        public void onUserVideoAvailable(String userId, boolean available) {
            int index = mRemoteUidList.indexOf(userId);
            Log.d(TAG, "onUserVideoAvailable index " + index + ", available " + available + " userId " + userId);
            if (available) {
                if (index == -1 && !userId.equals(mRoomId)) { //找不到
                    mRemoteUidList.add(userId);
                    refreshRemoteVideoViews();
                } else if (userId.equals(mRoomId)) {
                    mTRTCCloud.startRemoteView(userId, mAnchorPreviewView);
                    mBigPreviewMuteVideoDefault.setVisibility(View.GONE);
                }
            } else {
                if (index != -1 && !userId.equals(mRoomId)) { //找到
                    // 关闭用户userId的视频画面
                    mTRTCCloud.stopRemoteView(userId);
                    mRemoteUidList.remove(index);
                    refreshRemoteVideoViews();
                } else if (userId.equals(mRoomId)) {
                    mBigPreviewMuteVideoDefault.setVisibility(View.VISIBLE);
                }
            }
        }

        @Override
        public void onRecvCustomCmdMsg(String s, int i, int i1, byte[] bytes) {
            super.onRecvCustomCmdMsg(s, i, i1, bytes);
            //userId	用户标识
            //cmdID	命令 ID
            //seq	消息序号
            //message	消息数据
            String message = new String(bytes);
            String msg = "userId = " + s + "消息内容 :" + message;
            Toast.makeText(LiveBaseActivity.this, msg, Toast.LENGTH_SHORT).show();

            //todo 主播端收到消息后 显示图片3s后消失

            downLoadToShowImg(message);




        }

        // SDK 错误通知回调，错误通知意味着 SDK 不能继续运行了
        @Override
        public void onError(int errCode, String errMsg, Bundle extraInfo) {
            Log.d(TAG, "sdk callback onError");
            LiveBaseActivity activity = mContext.get();
            if (activity != null) {
                Toast.makeText(activity, "onError: " + errMsg + "[" + errCode+ "]" , Toast.LENGTH_SHORT).show();
                if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
                    activity.exitRoom();
                }
            }
        }


        private void refreshRemoteVideoViews() {
            for (int i = 0; i < mRemoteViewList.size(); i++) {
                if (i < mRemoteUidList.size()) {
                    String remoteUid = mRemoteUidList.get(i);
                    mRemoteViewList.get(i).setVisibility(View.VISIBLE);
                    // 开始显示用户userId的视频画面
                    mTRTCCloud.startRemoteView(remoteUid, mRemoteViewList.get(i).getVideoView());
                } else {
                    mRemoteViewList.get(i).setVisibility(View.GONE);
                }
            }
        }
    }



    protected class LiveSubViewListenerImpl implements LiveSubVideoView.LiveSubViewListener {

        private int mIndex;

        public LiveSubViewListenerImpl (int index) {
            mIndex = index;
        }

        @Override
        public void onMuteRemoteAudioClicked(View view) {
            boolean isSelected = view.isSelected();
            if (!isSelected) {
                mTRTCCloud.muteRemoteAudio(mRemoteUidList.get(mIndex),true);
                view.setBackground(getResources().getDrawable(R.mipmap.live_subview_sound_mute));
            } else {
                mTRTCCloud.muteRemoteAudio(mRemoteUidList.get(mIndex),false);
                view.setBackground(getResources().getDrawable(R.mipmap.live_subview_sound_unmute));
            }
            view.setSelected(!isSelected);
        }

        @Override
        public void onMuteRemoteVideoClicked(View view) {
            boolean isSelected = view.isSelected();
            if (!isSelected) {
                mTRTCCloud.stopRemoteView(mRemoteUidList.get(mIndex));
                mRemoteViewList.get(mIndex).getMuteVideoDefault().setVisibility(View.VISIBLE);
                view.setBackground(getResources().getDrawable(R.mipmap.live_subview_video_mute));
            } else {
                mTRTCCloud.startRemoteView(mRemoteUidList.get(mIndex), mRemoteViewList.get(mIndex).getVideoView());
                view.setBackground(getResources().getDrawable(R.mipmap.live_subview_video_unmute));
                mRemoteViewList.get(mIndex).getMuteVideoDefault().setVisibility(View.GONE);
            }
            view.setSelected(!isSelected);
        }
    }

    protected void exitRoom() {
        mTRTCCloud.stopLocalAudio();
        mTRTCCloud.stopLocalPreview();
        mTRTCCloud.exitRoom();
        mRemoteUidList.clear();
        mRemoteViewList.clear();
    }

    //////////////////////////////////    动态权限申请   ////////////////////////////////////////

    protected boolean checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> permissions = new ArrayList<>();
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)) {
                permissions.add(Manifest.permission.CAMERA);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)) {
                permissions.add(Manifest.permission.RECORD_AUDIO);
            }
            if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
            }
            if (permissions.size() != 0) {
                ActivityCompat.requestPermissions(LiveBaseActivity.this,
                        permissions.toArray(new String[0]),
                        REQ_PERMISSION_CODE);
                return false;
            }
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQ_PERMISSION_CODE:
                for (int ret : grantResults) {
                    if (PackageManager.PERMISSION_GRANTED == ret) {
                        mGrantedCount ++;
                    }
                }
                if (mGrantedCount == permissions.length) {
                    initView();
                    enterRoom(); //首次启动，权限都获取到，才能正常进入通话
                } else {
                    Toast.makeText(this, "用户没有允许需要的权限，加入通话失败", Toast.LENGTH_SHORT).show();
                }
                mGrantedCount = 0;
                break;
            default:
                break;
        }
    }

    protected abstract void enterRoom();

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.ic_back) {
            finish();
        } else if (id == R.id.live_btn_log_info) {
            showDebugView();
        } else if (id == R.id.live_btn_send_msg) {
            showEditMsgDialog();
        } else if (id == R.id.live_btn_choose_photo) {
            selectImage();
        }


    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);


        //选择系统图库的照片后去上传照片页面
        if ( resultCode == RESULT_OK && data != null) {
            Uri uri = data.getData();
            Intent intent = new Intent(this, TenCentStorageActivity.class);
            intent.putExtra("uri", uri);
            startActivityForResult(intent, 1);
        }

        //上传图片后主播需要发送携带fileId的通知给观众端
        if (requestCode == 1 && resultCode == 0  && data != null) {
            String msg = data.getStringExtra("fileId");
            sendMsg(msg);
        }


    }



    private void selectImage() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Browser Image..."), REQUEST_GET_IMAGE);
    }

    private void showEditMsgDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(LiveBaseActivity.this);
        View view = LayoutInflater.from(LiveBaseActivity.this).inflate(R.layout.dialog_edit_text, null);
        TextView cancel = view.findViewById(R.id.txt_cancel);
        TextView sure = view.findViewById(R.id.txt_sure);
        final EditText edtMsg = view.findViewById(R.id.edt_msg);
        final Dialog dialog = builder.create();
        dialog.show();
        dialog.getWindow().setContentView(view);
        //使editext可以唤起软键盘
        dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v){
                Toast.makeText(LiveBaseActivity.this, "cancel", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });
        sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v){
                //Toast.makeText(LiveBaseActivity.this, "sure", Toast.LENGTH_SHORT).show();
                //btn.setText(edtMsg.getText().toString() + "");
                String msgContent = edtMsg.getText().toString().trim();
                if (!"".equals(msgContent)) {
                    sendMsg(msgContent);
                } else {
                    Toast.makeText(LiveBaseActivity.this, "您还没有输入发送的消息内容", Toast.LENGTH_SHORT).show();
                }

                dialog.dismiss();
            }
        });
    }

    private void sendMsg(String msgContent) {
        byte[] ascii = msgContent.getBytes();
        boolean isSuccess = mTRTCCloud.sendCustomCmdMsg(1,ascii,false,false);
        String b = isSuccess ? "成功" : "失败";
        Toast.makeText(LiveBaseActivity.this, "发送消息" + b, Toast.LENGTH_SHORT).show();
    }

    private void showDebugView() {
        mLogLevel = (mLogLevel + 1) % 3;
        mLogInfoButton.setBackgroundResource((0 == mLogLevel) ? R.mipmap.live_log_close : R.mipmap.live_log_open);
        mTRTCCloud.showDebugView(mLogLevel);
    }

    private void downLoadToShowImg(String fileId) {
        downloadRequest(fileId);
    }

    private void downloadRequest(String fileId) {

        HttpUtil httpUtil = new HttpUtil(ContextHolder.getContext());

        String url = "https://api.vieewer.com/files/url/v1/" + fileId;
        Log.i("yjj", "base download request url = " + url);

        httpUtil.setUrl(url);


        httpUtil.setListener(new HttpUtil.HttpUtilListener() {

            @Override
            public void onCancelled(Callback.CancelledException arg0) {
                Log.i("yjj", "downloadRequest onCancelled" + arg0.getMessage());

            }

            @Override
            public void onError(Throwable arg0, boolean arg1) {
                Log.i("yjj", "downloadRequest onError" + arg0.getMessage());

            }

            @Override
            public void onFinished() {
                Log.i("yjj", "downloadRequest onFinished");
            }

            @Override
            public void onSuccess(String result) {
                Log.i("yjj", "downloadRequest onSuccess" + result);

                JSONObject jsonObject = null;
                try {
                    jsonObject = new JSONObject(result);
                    if ("200".equals(jsonObject.optString("code"))) {
                        String imgUrl = jsonObject.optString("data");
                        showImg(imgUrl);
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }

        }).get();


    }



    private void showImg(String imgUrl) {
        Log.i("yjj", "img url >>>>>>" + imgUrl);
        //PicUtils.savePic(TenCentStorageActivity.this, imgUrl);
        //PicUtils.load(TenCentStorageActivity.this, mDownloadImg, "http://www.jcodecraeer.com/uploads/20140731/67391406772378.png");

        RequestParams params = new RequestParams(imgUrl);

        // 默认缓存存活时间, 单位:毫秒（如果服务器没有返回有效的max-age或Expires则参考）
        params.setCacheMaxAge(1000 * 60);

        x.http().get(params, new Callback.ProgressCallback<File>() {
            @Override
            public void onSuccess(File result) {
                Log.i("yjj", "download onSuccess" + result.getPath());

                PicUtils.load(LiveBaseActivity.this, mShowImg, result, true);
                mShowImg.setVisibility(View.VISIBLE);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mShowImg.setVisibility(View.GONE);
                    }
                }, 3*1000);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.i("yjj", "download onError");
            }

            @Override
            public void onCancelled(CancelledException cex) {
                Log.i("yjj", "download onCancelled");
            }

            @Override
            public void onFinished() {
                Log.i("yjj", "download onFinished");
            }


            @Override
            public void onWaiting() {
                Log.i("yjj", "download onWaiting");
            }

            @Override
            public void onStarted() {
                Log.i("yjj", "download onStarted 开始下载");
            }

            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                Log.i("yjj", "download onLoading");
            }

        });
    }

}
